package io.gitee.zhangbinhub.acp.cloud

import io.gitee.zhangbinhub.acp.boot.tools.EnvironmentTools
import io.gitee.zhangbinhub.acp.cloud.constant.AcpCloudConstant
import io.gitee.zhangbinhub.acp.cloud.constant.AcpCloudLogConstant
import org.springframework.boot.SpringApplication
import org.springframework.boot.env.EnvironmentPostProcessor
import org.springframework.cloud.function.context.FunctionProperties
import org.springframework.core.env.ConfigurableEnvironment
import org.springframework.util.MimeTypeUtils

/**
 * 日志服务自动配置
 *
 * @since JDK 17
 */
class AcpCloudLogServerEnvironmentPostProcessor : EnvironmentPostProcessor {
    private val overridePropertiesName = "acpCloudLogServerOverridesProperties"
    private val defaultPropertiesName = "acpCloudLogServerDefaultProperties"
    private val logServerEnabled = "${AcpCloudConstant.LOG_SERVER_PROPERTIES_PREFIX}.enabled"
    private val logServerClientEnabled = "${AcpCloudConstant.LOG_SERVER_CLIENT_PROPERTIES_PREFIX}.enabled"
    private val logServerDestination = "${AcpCloudConstant.LOG_SERVER_PROPERTIES_PREFIX}.destination"
    private val logServerGroupId = "${AcpCloudConstant.LOG_SERVER_PROPERTIES_PREFIX}.group-id"
    private val functionDefinitionProperties = "${FunctionProperties.PREFIX}.definition"
    private val logConsumerBindName = "${AcpCloudLogConstant.CONSUMER}-in-0"
    private val defaultDestination = AcpCloudConstant.LOG_SERVER_DEFAULT_MESSAGE_TOPIC
    private val defaultGroupId = AcpCloudConstant.LOG_SERVER_DEFAULT_GROUP_ID

    override fun postProcessEnvironment(environment: ConfigurableEnvironment?, application: SpringApplication?) {
        if (environment!!.containsProperty(logServerEnabled)) {
            if ("true".equals(environment.getProperty(logServerEnabled), ignoreCase = true)) {
                val overrides: MutableMap<String, Any> = HashMap()
                var definition = AcpCloudLogConstant.CONSUMER
                if (environment.containsProperty(functionDefinitionProperties)) {
                    val property = environment.getProperty(functionDefinitionProperties)
                    if (property != null && property.contains(definition)) {
                        return
                    }
                    definition = "$property;$definition"
                }
                overrides[functionDefinitionProperties] = definition
                EnvironmentTools.addOrReplaceProperty(
                    environment.propertySources,
                    overrides,
                    overridePropertiesName,
                    true
                )

                val default: MutableMap<String, Any> = HashMap()
                "spring.cloud.stream".let { prefix ->
                    default["$prefix.function.bindings.$logConsumerBindName"] = AcpCloudLogConstant.INPUT
                    val destination = environment.getProperty(logServerDestination, defaultDestination)
                    val groupId = environment.getProperty(logServerGroupId, defaultGroupId)
                    default["$prefix.bindings.${AcpCloudLogConstant.INPUT}.destination"] = destination
                    default["$prefix.bindings.${AcpCloudLogConstant.INPUT}.contentType"] = MimeTypeUtils.APPLICATION_JSON_VALUE
                    default["$prefix.bindings.${AcpCloudLogConstant.INPUT}.group"] = groupId
                    EnvironmentTools.addOrReplaceProperty(
                        environment.propertySources,
                        default,
                        defaultPropertiesName,
                        false
                    )
                }
            }
        }
        if (environment.containsProperty(logServerClientEnabled)) {
            if ("true".equals(environment.getProperty(logServerClientEnabled), ignoreCase = true)) {
                val default: MutableMap<String, Any> = HashMap()
                "spring.cloud.stream".let { prefix ->
                    val destination = environment.getProperty(logServerDestination, defaultDestination)
                    default["$prefix.bindings.${AcpCloudLogConstant.OUTPUT}.destination"] = destination
                    default["$prefix.bindings.${AcpCloudLogConstant.OUTPUT}.contentType"] = MimeTypeUtils.APPLICATION_JSON_VALUE
                    EnvironmentTools.addOrReplaceProperty(
                        environment.propertySources,
                        default,
                        defaultPropertiesName,
                        false
                    )
                }
            }
        }
    }
}
